//{=================================================================================
//! @file    b1.cpp
//! @date    2013-09-28 17:25
//! @author  Anton Samsonov <Fivapr...@inbox.ru>
//!
//! @mainpage   Hello! This is documentation for control 2007.
//!             You'd better check warning.
//!
//! Program checking if square divisor of number exists.
//!
//! @par    Program gets a number - n (n < pow (2, 31).         \
            Check if there is square divisor of this nubmer. \
            Output "YES" if it exists and "NO" if not.
//!
//! @note   Version 0.1
//!         - Added OUT     (ifdef _EJC).
//!         - Added EJC_OUT (if _EJC is not defined)
//!         - Added ASSERT  (ifdef DEBUG).
//!         - Added square_divisor (a) function.
//!         - First aim of program is succeed
//!
//! @todo   - ...
//!
//! @warning  Keep calm and do science!
//}=================================================================================

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#ifdef _EJC
    #define OUT printf
    #define EJC_OUT if (0) printf
#else
    #define OUT if (0) printf
    #define EJC_OUT printf
#endif //!< Macro for ejudge system.
//----------------------------------------
#define DEBUG
//----------------------------------------

#ifdef DEBUG
    #define ASSERT( cond )                          \
    if (!(cond)) {                                  \
        fprintf (stderr, "# Assertion fail : %s."   \
                        "File %s, line %d\n",       \
                        #cond, __FILE__, __LINE__); \
        abort();                                    \
    }
#else
    #define ASSERT( cond )
#endif //!< ASSERT is active only when DEBUG is defined.

//! we can use 0.000001, because sqrt ( pow(2, 31)) - sqrt ( pow(2, 31) - 1) > 0.000001
const double EPSILON = 0.e-6;

int square_divisor (int a);

int main()
{
    OUT ("# This is %s. It's compiled %s %s by Anton Samsonov\n", __FILE__, __DATE__, __TIME__);

    int scanned = 0;
    OUT ("# Input a number you want to check.\n");
    int scanf_ret = scanf("%d", &scanned);
    if (scanf_ret < 1) { OUT ("# Input is not valid. You need to input positive decimal number.\n"); return 1; }

    int func_ret = square_divisor (scanned);
    if (func_ret) {
        EJC_OUT ("YES\n");
        OUT ("# Yes, square divisor of this number exists, for example: %d.\n", func_ret);
    }
    else {
        EJC_OUT ("NO\n");
        OUT ("# No, this number has no square divisors.\n");
    }

    return 0;
}

/**
    square_divisor - checking square divisor of a exists.

    @param    a    Number you need to check.

    @return        It returns square divisor of a \
                   or 0 if it's not existing.

    @note          It doesn.t work for long arithmetic.
**/

int square_divisor (int a)
{
//! we store value of sqrt (a) to save time.
    double sqrt_val = sqrt (a) + EPSILON;

//! It works 2 times faster if we check only odd counter values.\
    That's why we need to check these values of a.
    if (a == 1)     return 0;
    if (a == 4)     return 2;
    if (a % 4 == 0) return 2;

//! As we checked 2*2, we can start from 3*3.
    int i = 3; //!< counter
    for (i = 3; i < sqrt_val; i += 2) {
        if (a % (i * i) == 0) return i * i;
    }

    return 0;
}
